using System;
using System.Text;

using Grr.External;

namespace Grr {
	
	public static class StringUtil {
		public static readonly int MaxCleanLength = 255;

		public static string ToFriendlyUri(string input)
		{
			StringBuilder res = new StringBuilder();

			int i = 0;
			while (i < input.Length && Char.IsWhiteSpace(input[i]))
				++i;

			for (; i < input.Length; i++) {
				char c = input[i];

				if (Char.IsLetterOrDigit(c)) {
					res.Append(c);
					continue;
				}

				switch (c) {
					case '-':
						res.Append('_');
						continue;
					case '.':
						res.Append("-dot-");
						break;
				}

				if (Char.IsWhiteSpace(c)) {
					while (i + 1 < input.Length && Char.IsWhiteSpace(input[i + 1]))
						++i;
					if (i != input.Length - 1)
						res.Append('-');
				}
			}

			return res.ToString ();
		}

		public static string ToDb(string input)
		{
			if (input == null || input == String.Empty)
				return String.Empty;

			StringBuilder res = new StringBuilder();
			for (int i = 0; i < input.Length; i++) {
				char c = input[i];

				if (Char.IsLetterOrDigit(c)) {
					res.Append(c);
					continue;
				}

				if (c == '_') {
					res.Append('-');
					continue;
				}

				if (c == '-') {
					if (input.IndexOf("-dot-", i) == i) {
						res.Append('.');
						i += "dot-".Length;
					} else {
						res.Append(' ');
					}
				}

				if (Char.IsWhiteSpace(c)) {
					res.Append(' ');
				}
			}

			return res.ToString();
		}

		// A clean string is letters, digits, spaces (only space, no other white
		// space) and the following characters:  .~!_-,.  The max length of a clean
		// string is 40 characters.  If any bad characters are found they will be removed
		// if the string is over 255 characters, it will be truncated.	All whitespace characters 
		// will be converted to a space.  Multiple whitespace characters will be compressed into
		// a single space.
		public static string Clean(string input)
		{
			return CleanInternal(input, true);
		}

		// This function is the same as the Clean function except it does not allow the
		// puncuation characters that clean string allows.
		public static string CleanNoPunc(string input)
		{
			return CleanInternal(input, false);
		}

		private static string CleanInternal (string input, bool allow_punc)
		{
			StringBuilder res = new StringBuilder(Math.Min(input.Length, MaxCleanLength));
			for (int i = 0; i < MaxCleanLength && i < input.Length; i++) {
				char c = input[i];

				if (Char.IsLetterOrDigit(c)) {
					res.Append(c);
					continue;
				}

				if (Char.IsWhiteSpace(c)) {
					res.Append(' ');
					while (i + 1 < input.Length && Char.IsWhiteSpace(input[i + 1]))
						++i;
					continue;
				}

				if (allow_punc)	{
					switch (c) {
						case '.':
						case '~':
						case '!':
						case '_':
						case '-':
						case ',':
							res.Append(c);
							continue;
					}
				}
			}

			return res.ToString();
		}

		public static string GetAdditions(string left, string right)
		{
			Diff.Item [] diffs = Diff.DiffText(left, right, false, true, false);

			return right;
		}

		public static string Ellipsis(string value, int length)
		{
			return String.Concat(value.Substring(0, length - 3), "...");
		}
	}
}


